#include <iostream>
#include <cstdlib>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

typedef int Status;
typedef int ElemType;

class SqStack
{
private:
	ElemType *base, *top;
	int stacksize;
public:
	SqStack();
	Status InitStack();
	Status DestroyStack();
	Status ClearStack();
	bool StackEmpty();
	int StackLength();
	Status GetTop(ElemType &e);
	Status Push(ElemType e);
	Status Pop(ElemType &e);
	Status StackTraverse(Status (*func)(ElemType e));
};

SqStack::SqStack()
{
	Status st = this->InitStack();
	if(st != 1)
		exit(ERROR);
}

Status SqStack::InitStack()
{
	this->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
	if(!this->base)
		exit(OVERFLOW);
	this->top = this->base;
	this->stacksize = STACK_INIT_SIZE;
	return OK;
}

Status SqStack::DestroyStack()
{
	free(this->base);
	this->top = this->base = NULL;
	return OK;
}

Status SqStack::ClearStack()
{
	this->top = this->base;
	return OK;
}

bool SqStack::StackEmpty()
{
	return (this->top) == (this->base);
}

int SqStack::StackLength()
{
	return (this->top)-(this->base);
}

Status SqStack::GetTop(ElemType &e)
{
	e = *(top-1);
	return OK;
}

Status SqStack::Push(ElemType e)
{
	if(this->top - this->base >= this->stacksize)
	{
		this->base = (ElemType *)realloc(this->base, (STACK_INIT_SIZE + STACKINCREMENT) * sizeof(ElemType));
		if(!this->base)
			exit(OVERFLOW);
		this->top = this->base + this->stacksize;
	}
	*(this->top) = e;
	(this->top)++;
	return OK;
}

Status SqStack::Pop(ElemType &e)
{
	if(this->top == this->base)
		return ERROR;
	e = *(--this->top);
	return OK;
}

Status SqStack::StackTraverse(Status (*func)(ElemType e))
{
	ElemType *p;
	Status st;
	for(p = base; p < top; p++)
	{
		st = (*func)(*p);
		if(st != OK)
			return st;
	}
	return OK;
}
